/**
 * 
 */
package truerefactor.input;

import japa.parser.ast.CompilationUnit;

import java.io.File;
import java.util.List;

import truerefactor.graph.AttributeNode;
import truerefactor.graph.ClassNode;
import truerefactor.graph.CodeGraph;
import truerefactor.graph.CodeNode;
import truerefactor.graph.MethodNode;
import truerefactor.graph.ModifierParams;
import truerefactor.graph.PackageNode;
import truerefactor.graph.StatementNode;
import truerefactor.graph.StatementType;
import truerefactor.graph.TypePair;

/**
 * GraphParser - Abstract class defining the interface for all code to graph
 * parsing classes, which utilize some parser and a known language to generate
 * the graph.
 * 
 * @author Isaac Griffith
 */
public abstract class GraphParser {

    /**
     * The Code Graph to be created
     */
    protected CodeGraph graph;
    /**
     * The current file being parsed
     */
    protected File file;

    /**
     * Creates all the connections in the graph based on the provided
     * compilation unit. Note that the CompilationUnit class is dependent on the
     * version of the Java Parser developed by JavaCC. This will eventually need
     * to be changed
     * 
     * @param cu
     */
    public abstract void buildConnections(CompilationUnit cu);

    /**
     * Adds an attribute to the provided class node, with the provided field
     * name, code, type and modifiers
     * 
     * @param cNode
     *            class to associate the attribute with
     * @param fieldName
     *            name of the attribute
     * @param code
     *            code for the attribute
     * @param type
     *            type of the attribute
     * @param modifiers
     *            A ModifierParam object representing all the modifiers for the
     *            new attribute
     * @return the newly created AttributeNode
     */
    public abstract AttributeNode addAttribute(ClassNode cNode, String fieldName, String code, String type,
            ModifierParams modifiers);

    /**
     * Creates a new statement node based on the provided parameters
     * 
     * @param cNode
     *            node to which the statement belongs (method node)
     * @param stmtGraph
     *            statement graph in which the statement is a part of
     * @param type
     *            StatmentType constant describing the type of statement
     * @param code
     *            the code for the statement
     * @return the newly created statement node
     */
    public abstract StatementNode addStatement(CodeNode cNode, CodeGraph stmtGraph, StatementType type, String code);

    /**
     * Creats a new MethodNode based on the provided parameters.
     * 
     * @param cNode
     *            Class in which the method resides
     * @param methodName
     *            name of the new method
     * @param params
     *            list of parameter names for the method
     * @param paramInfo
     *            list of type information for provided parameter names
     * @param code
     *            the underlying code of the method
     * @param type
     *            return type of the method
     * @param modifiers
     *            the modifier info for the method
     * @return the newly create method node
     */
    public abstract MethodNode addMethod(ClassNode cNode, String methodName, List<String> params,
            List<TypePair> paramInfo, String code, String type, ModifierParams modifiers);

    /**
     * Creates a new PackageNode with the given parameters.
     * 
     * @param fullName
     *            The fully qualified package name
     * @param packageName
     *            the simple name of the package
     * @param code
     *            code for the package
     * @return the newly created PackageNode
     */
    public abstract PackageNode addPackage(String fullName, String packageName, String code);

    /**
     * Creates a new class with the provided parameters, in the current package
     * 
     * @param className
     *            name of the class to be created
     * @param modifier
     *            Parameters describing the modifiers for the class to be
     *            created
     * @return
     */
    public abstract ClassNode addClass(String className, ModifierParams modifier);

    /**
     * Starts the process of parsing from code to graph.
     * 
     * @param obj
     *            initial object to start the parsing on
     */
    public abstract void start(Object obj);

    /**
     * Sets the code graph that will be the initial code graph generated.
     * 
     * @param graph
     *            graph to be filled in by the graph parser.
     */
    public void setGraph(CodeGraph graph)
    {
        this.graph = graph;
    }

    /**
     * Sets the current file to be parsed to the provided file
     * 
     * @param file
     *            file to parse
     */
    public void setFile(File file)
    {
        this.file = file;
    }

    /**
     * determines the LOC of the provided file
     * 
     * @param file
     *            file to measure LOC of
     * @return LOC of the provided file, where LOC is the language dependent
     *         Lines of Actual Code
     */
    public abstract int getLinesOfCode(File file);
}
